home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / intuisup.lha / Intuisup / source.lha / Editor / load.c < prev    next >
C/C++ Source or Header  |  1992-10-05  |  19KB  |  884 lines

  1. /* $Revision Header *** Header built automatically - do not edit! ***********
  2.  *
  3.  *    (C) Copyright 1991 by Torsten Jürgeleit
  4.  *
  5.  *    Name .....: load.c
  6.  *    Created ..: Sunday 22-Dec-91 21:22:44
  7.  *    Revision .: 2
  8.  *
  9.  *    Date        Author                 Comment
  10.  *    =========   ====================   ====================
  11.  *    02-Oct-92   Michael Bjerking       New realese, better Screen/Window editor
  12.  *    31-Dec-91   Torsten Jürgeleit      new font management
  13.  *    22-Dec-91   Torsten Jürgeleit      Created this file!
  14.  *
  15.  ****************************************************************************
  16.  *
  17.  *    Load template files
  18.  *
  19.  * $Revision Header ********************************************************/
  20.  
  21.  /* Includes */
  22.  
  23. #include "includes.h"
  24. #include "defines.h"
  25. #include "imports.h"
  26. #include "protos.h"
  27.  
  28.  /* Defines */
  29.  
  30. #define LOAD_FILE_READ_BUFFER_SIZE    2000
  31. #define LOAD_FILE_LINE_BUFFER_SIZE    80
  32. #define LOAD_FILE_FLAGS            (TEXT_FILE_FLAG_TRIM_LINE | TEXT_FILE_FLAG_SKIP_COMMENTS | TEXT_FILE_FLAG_SKIP_EMPTY_LINES | TEXT_FILE_FLAG_LINE_CONTINUATION)
  33.  
  34. #define BLOCK_TYPE_NONE        0
  35. #define BLOCK_TYPE_HEADER    1
  36. #define BLOCK_TYPE_FONT        2
  37. #define BLOCK_TYPE_TEMPLATE    3
  38. #define BLOCK_TYPE_BOX        4
  39. #define BLOCK_TYPE_TEXTLIST    5
  40. #define BLOCK_TYPE_BORDERDATA    6
  41. #define BLOCK_TYPE_TEXTDATA    7
  42. #define BLOCK_TYPE_GADGETDATA    8
  43.  
  44. #define HEADER_ITEM_TYPE_LEFTEDGE    1
  45. #define HEADER_ITEM_TYPE_TOPEDGE        2
  46. #define HEADER_ITEM_TYPE_WIDTH        3
  47. #define HEADER_ITEM_TYPE_HEIGHT        4
  48. #define HEADER_ITEM_TYPE_MINW            5
  49. #define HEADER_ITEM_TYPE_MINH            6
  50. #define HEADER_ITEM_TYPE_MAXW            7
  51. #define HEADER_ITEM_TYPE_MAXH            8
  52. #define HEADER_ITEM_TYPE_DETAILPEN    9
  53. #define HEADER_ITEM_TYPE_BLOCKPEN    10
  54. #define HEADER_ITEM_TYPE_FLAGS        11
  55. #define HEADER_ITEM_TYPE_WINFLAGS    12
  56. #define HEADER_ITEM_TYPE_IDCMPFLAGS    13
  57. #define HEADER_ITEM_TYPE_ID            14
  58. #define HEADER_ITEM_TYPE_NAME            15
  59.  
  60. #define FONT_ITEM_TYPE_NAME        1
  61. #define FONT_ITEM_TYPE_YSIZE        2
  62.  
  63. #define TEMPLATE_ITEM_TYPE_NAME        1
  64. #define TEMPLATE_ITEM_TYPE_TYPE        2
  65. #define TEMPLATE_ITEM_TYPE_FLAGS    3
  66.  
  67. #define BOX_ITEM_TYPE_X1        1
  68. #define BOX_ITEM_TYPE_Y1        2
  69. #define BOX_ITEM_TYPE_X2        3
  70. #define BOX_ITEM_TYPE_Y2        4
  71.  
  72. #define TEXTLIST_ITEM_TYPE_TEXT        1
  73.  
  74. #define BORDERDATA_ITEM_TYPE_TYPE    1
  75.  
  76. #define TEXTDATA_ITEM_TYPE_TYPE        1
  77. #define TEXTDATA_ITEM_TYPE_FLAGS    2
  78. #define TEXTDATA_ITEM_TYPE_TEXT        3
  79. #define TEXTDATA_ITEM_TYPE_TEXTATTR    4
  80.  
  81. #define GADGETDATA_ITEM_TYPE_TYPE    1
  82. #define GADGETDATA_ITEM_TYPE_FLAGS    2
  83. #define GADGETDATA_ITEM_TYPE_TEXT    3
  84. #define GADGETDATA_ITEM_TYPE_TEXTATTR    4
  85. #define GADGETDATA_ITEM_TYPE_SPECIAL1    5
  86. #define GADGETDATA_ITEM_TYPE_SPECIAL2    6
  87. #define GADGETDATA_ITEM_TYPE_SPECIAL3    7
  88.  
  89.  /* Statics */
  90.  
  91. STATIC struct TemplateList new_template_list;
  92. STATIC struct TemplateFont *new_font;
  93. STATIC struct Template *new_template;
  94.  
  95. STATIC BYTE *block_keywords[]=
  96. {
  97.     "PROJECTHEADER",
  98.     "FONT",
  99.     "TEMPLATE",
  100.     "BOX",
  101.     "TEXTLIST",
  102.     "BORDERDATA",
  103.     "TEXTDATA",
  104.     "GADGETDATA",
  105.     NULL
  106. };
  107. STATIC BYTE *header_keywords[]=
  108. {
  109.     "LEFTEDGE",
  110.     "TOPEDGE",
  111.     "WIDTH",
  112.     "HEIGHT",
  113.     "MINW",
  114.     "MINH",
  115.     "MAXW",
  116.     "MAXH",
  117.     "DETAILPEN",
  118.     "BLOCKPEN",
  119.     "FLAGS",
  120.     "WINFLAGS",
  121.     "IDCMPFLAGS",
  122.     "ID",
  123.     "NAME",
  124.     NULL
  125. };
  126. STATIC BYTE *font_keywords[]=
  127. {
  128.     "NAME",
  129.     "YSIZE",
  130.     NULL
  131. };
  132. STATIC BYTE *template_keywords[]=
  133. {
  134.     "NAME",
  135.     "TYPE",
  136.     "FLAGS",
  137.     NULL
  138. };
  139. STATIC BYTE *box_keywords[]=
  140. {
  141.     "X1",
  142.     "Y1",
  143.     "X2",
  144.     "Y2",
  145.     NULL
  146. };
  147. STATIC BYTE *textlist_keywords[]=
  148. {
  149.     "TEXT",
  150.     NULL
  151. };
  152. STATIC BYTE *borderdata_keywords[]=
  153. {
  154.     "TYPE",
  155.     NULL
  156. };
  157. STATIC BYTE *textdata_keywords[]=
  158. {
  159.     "TYPE",
  160.     "FLAGS",
  161.     "TEXT",
  162.     "TEXTATTR",
  163.     NULL
  164. };
  165. STATIC BYTE *gadgetdata_keywords[]=
  166. {
  167.     "TYPE",
  168.     "FLAGS",
  169.     "TEXT",
  170.     "TEXTATTR",
  171.     "SPECIAL1",
  172.     "SPECIAL2",
  173.     "SPECIAL3",
  174.     NULL
  175. };
  176.  /* Load project */
  177.  
  178. SHORT
  179. load_project(USHORT mode)
  180. {
  181.     struct rtFileRequester *freq = project_file_requester;
  182.     SHORT status = EDITOR_STATUS_NORMAL;
  183.     BYTE filename[256], buf[256];        /* <- should define a constant */
  184.     BYTE text[256];
  185.  
  186.     /* Display ReqTools file requester and check if user selected cancel */
  187.     IChangeMousePointer(ewin, NULL, FALSE);
  188.     if (mode == LOAD_MODE_NORMAL)
  189.     {
  190.         strcpy(text, PROJECT_LOAD_HAIL_TEXT);
  191.     }
  192.     else
  193.     {
  194.         strcpy(text, PROJECT_APPEND_HAIL_TEXT);
  195.     }
  196.     if (rtFileRequest(freq, filename, text, TAG_END))
  197.     {
  198.         struct TemplateList *new_tl = &new_template_list;
  199.         struct FileData *fd;
  200.         SHORT len = strlen(filename) - 4;
  201.  
  202.         /* Prepare file name and project name */
  203.         if (len < 1 || strcmp(filename + len, ".tpl"))
  204.         {
  205.             strcat(filename, ".tpl");
  206.             len += 4;
  207.         }
  208.  
  209.         /* path + filename */
  210.         if (strlen(freq->Dir) > 0)
  211.         {
  212.             strcpy(buf, filename);
  213.             if (strncmp(buf + strlen(buf) - 1, ":", (size_t) 1) == 0)
  214.                 sprintf(filename, "%s/%s", freq->Dir, buf);
  215.             else
  216.                 sprintf(filename, "%s%s", freq->Dir, buf);
  217.         }
  218.  
  219.         /* Open file */
  220.         if (!(fd = IOpenTextFile(filename, LOAD_FILE_READ_BUFFER_SIZE,
  221.                                  LOAD_FILE_LINE_BUFFER_SIZE, LOAD_FILE_FLAGS)))
  222.         {
  223.             status = EDITOR_ERROR_OPEN_FAILED;
  224.         }
  225.         else
  226.         {
  227.  
  228.             /* Init new template list */
  229.             NewList((struct List *) & new_tl->tl_Fonts);
  230.             NewList((struct List *) & new_tl->tl_Templates);
  231.             new_tl->tl_BorderTemplates = 0;
  232.             new_tl->tl_TextTemplates = 0;
  233.             new_tl->tl_GadgetTemplates = 0;
  234.             new_tl->tl_Flags = DEFAULT_TEMPLATE_LIST_FLAGS;
  235.  
  236.             /* Read all templates */
  237.             while ((status = parse_block(fd, new_tl, BLOCK_TYPE_NONE,
  238.                                          mode)) == EDITOR_STATUS_NORMAL);
  239.             /* Install and display new template list */
  240.             if (status == EDITOR_STATUS_EOF)
  241.             {
  242.                 struct TemplateList *tl = &template_list;
  243.                 struct TemplateFont *tf;
  244.                 struct Template *tp;
  245.                 struct List *list;
  246.  
  247.                 /* First set normal status */
  248.                 status = EDITOR_STATUS_NORMAL;
  249.  
  250.                 /* Remove unused template fonts from new template list */
  251.                 tf = get_head((struct List *) & new_tl->tl_Fonts);
  252.                 while (tf)
  253.                 {
  254.                     struct TemplateFont *next_tf = get_succ((struct Node *)
  255.                                                             & tf->tf_MinNode);
  256.                     if (!tf->tf_UseCount)
  257.                     {
  258.                         Remove((struct Node *) & tf->tf_MinNode);
  259.                         free_template_font(tf);
  260.                     }
  261.                     tf = next_tf;
  262.                 }
  263.                 if (mode == LOAD_MODE_NORMAL)
  264.                 {
  265.  
  266.                     /* Overwrite old template list */
  267.                     if ((status = new_project(tl, new_tl->tl_Flags)) ==
  268.                         EDITOR_STATUS_NORMAL)
  269.                     {
  270.                         /* Copy template fonts from new to original template list */
  271.                         list = (struct List *) & new_tl->tl_Fonts;
  272.                         while (tf = (struct TemplateFont *) RemHead(list))
  273.                         {
  274.                             AddTail((struct List *) & tl->tl_Fonts,
  275.                                     (struct Node *) & tf->tf_MinNode);
  276.                         }
  277.  
  278.                         /* Copy templates from new to original template list */
  279.                         list = (struct List *) & new_tl->tl_Templates;
  280.                         while (tp = (struct Template *) RemHead(list))
  281.                         {
  282.                             add_template_to_list(tl, tp, FALSE);
  283.                             display_template(tp);
  284.                         }
  285.  
  286.                         /* Copy template list data */
  287.                         tl->tl_Flags = new_tl->tl_Flags &
  288.                             ~TEMPLATE_LIST_FLAG_CHANGED;
  289.                         strcpy(&tl->tl_ProjectID[0], &new_tl->tl_ProjectID[0]);
  290.                         change_project_name(tl, filename, len);
  291.                     }
  292.                 }
  293.                 else
  294.                 {
  295.  
  296.                     /* Append new template list to old one */
  297.                     list = (struct List *) & new_tl->tl_Templates;
  298.                     while (tp = (struct Template *) RemHead(list))
  299.                     {
  300.                         struct TextAttr *old_ta, *new_ta;
  301.  
  302.                         /* Open template font in original template list and close it in new one */
  303.                         switch (TEMPLATE_GROUP(tp))
  304.                         {
  305.                         case TEMPLATE_GROUP_TEXT:
  306.                             old_ta = tp->tp_Data.tp_TextData.td_TextAttr;
  307.                             if (!(new_ta = open_template_font_by_attributes(tl,
  308.                                                                             (BYTE *) old_ta->ta_Name, old_ta->ta_YSize)))
  309.                             {
  310.                                 status = EDITOR_ERROR_INVALID_FONT;
  311.                             }
  312.                             else
  313.                             {
  314.                                 tp->tp_Data.tp_TextData.td_TextAttr = new_ta;
  315.                                 close_template_font(new_tl, old_ta);
  316.                             }
  317.                             break;
  318.  
  319.                         case TEMPLATE_GROUP_GADGET:
  320.                             old_ta = tp->tp_Data.tp_GadgetData.gd_TextAttr;
  321.                             if (!(new_ta = open_template_font_by_attributes(tl,
  322.                                                                             (BYTE *) old_ta->ta_Name, old_ta->ta_YSize)))
  323.                             {
  324.                                 status = EDITOR_ERROR_INVALID_FONT;
  325.                             }
  326.                             else
  327.                             {
  328.                                 tp->tp_Data.tp_GadgetData.gd_TextAttr = new_ta;
  329.                                 close_template_font(new_tl, old_ta);
  330.                             }
  331.                             break;
  332.                         }
  333.  
  334.                         if (status != EDITOR_STATUS_NORMAL)
  335.                         {
  336.                             free_template(new_tl, tp);
  337.                         }
  338.                         else
  339.                         {
  340.  
  341.                             /* Add template to original template list */
  342.                             if (tp->tp_Flags & TEMPLATE_FLAG_DEFAULT_NAME)
  343.                             {
  344.                                 add_template_to_list(tl, tp, TRUE);
  345.                             }
  346.                             else
  347.                             {
  348.                                 add_template_to_list(tl, tp, FALSE);
  349.                             }
  350.                             display_template(tp);
  351.                             tl->tl_Flags |= TEMPLATE_LIST_FLAG_CHANGED;
  352.                         }
  353.                     }
  354.                 }
  355.                 if (status == EDITOR_STATUS_NORMAL)
  356.                 {
  357.                     ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, 0L,
  358.                                          USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_Templates);
  359.                 }
  360.             }
  361.             ICloseTextFile(fd);
  362.  
  363.             /* If error then free incomplete loaded template list */
  364.             if (status != EDITOR_STATUS_NORMAL)
  365.             {
  366.                 free_template_list(new_tl);
  367.             }
  368.         }
  369.     }
  370.     IRestoreMousePointer(ewin);
  371.     if (status != EDITOR_STATUS_NORMAL)
  372.     {
  373.         show_error(status);
  374.     }
  375.     return (status);
  376. }
  377.  
  378.  /* Parse block of load file */
  379.  
  380. STATIC SHORT
  381. parse_block(struct FileData * fd, struct TemplateList * tl,
  382.             USHORT block_type, USHORT mode)
  383. {
  384.     SHORT status = EDITOR_STATUS_NORMAL;
  385.  
  386.     if (block_type == BLOCK_TYPE_FONT)
  387.     {
  388.         struct TemplateFont *tf;
  389.  
  390.         if (!(tf = new_font = AllocMem((LONG) sizeof(struct TemplateFont),
  391.                                         (LONG) MEMF_PUBLIC | MEMF_CLEAR)))
  392.         {
  393.             status = EDITOR_ERROR_OUT_OF_MEM;
  394.         }
  395.         else
  396.         {
  397.             struct TextAttr *ta = &tf->tf_TextAttr;
  398.  
  399.             /* Init new template font */
  400.             ta->ta_Style = FS_NORMAL;
  401.             ta->ta_Flags = FPF_ROMFONT;
  402.             tf->tf_UseCount = 0;
  403.         }
  404.     }
  405.     else
  406.     {
  407.         if (block_type == BLOCK_TYPE_TEMPLATE)
  408.         {
  409.             struct Template *tp;
  410.  
  411.             if (!(tp = new_template = AllocMem((LONG) sizeof(struct Template),
  412.                                                 (LONG) MEMF_PUBLIC | MEMF_CLEAR)))
  413.             {
  414.                 status = EDITOR_ERROR_OUT_OF_MEM;
  415.             }
  416.             else
  417.             {
  418.  
  419.                 /* Init new template */
  420.                 NewList(&tp->tp_TextList);
  421.                 tp->tp_Node.ln_Name = &tp->tp_TemplateName[0];
  422.             }
  423.         }
  424.     }
  425.     if (status == EDITOR_STATUS_NORMAL)
  426.     {
  427.  
  428.         /* Block loop */
  429.         do
  430.         {
  431.             BYTE c, *keyword, *arg;
  432.  
  433.             switch (IReadTextLine(fd))
  434.             {
  435.             case TEXT_FILE_STATUS_NORMAL:
  436.  
  437.                 /* Mark end of keyword */
  438.                 keyword = arg = fd->fd_Line;
  439.                 while ((c = *arg++) != ' ' && c != '=' && c != '\0');
  440.                 if (c == '\0')
  441.                 {
  442.                     status = EDITOR_ERROR_NO_ARGUMENT;
  443.                 }
  444.                 else
  445.                 {
  446.                     *(arg - 1) = '\0';
  447.  
  448.                     /* Strip double quotes from string argument */
  449.                     if (*arg == '"')
  450.                     {
  451.                         arg++;
  452.                         *(arg + (strlen(arg) - 1)) = '\0';
  453.                     }
  454.  
  455.                     /* Check keyword */
  456.                     if (!strcmp(keyword, "BEGIN"))
  457.                     {
  458.  
  459.                         /* Begin new block */
  460.                         status = parse_block(fd, tl, search_keyword(arg,
  461.                                                                     &block_keywords[0]), mode);
  462.                     }
  463.                     else
  464.                     {
  465.                         if (!strcmp(keyword, "END"))
  466.                         {
  467.  
  468.                             /* End current block */
  469.                             if (search_keyword(arg, &block_keywords[0]) !=
  470.                                 block_type)
  471.                             {
  472.                                 status = EDITOR_ERROR_END_WRONG_BLOCK;
  473.                             }
  474.                             else
  475.                             {
  476.                                 status = EDITOR_STATUS_EOB;
  477.                             }
  478.                         }
  479.                         else
  480.                         {
  481.  
  482.                             /* Parse item */
  483.                             status = parse_item(tl, block_type, keyword, arg,
  484.                                                 mode);
  485.                         }
  486.                     }
  487.                 }
  488.                 break;
  489.  
  490.             case TEXT_FILE_STATUS_EOF:
  491.                 status = EDITOR_STATUS_EOF;
  492.                 break;
  493.  
  494.             case TEXT_FILE_ERROR_LINE_TOO_LONG:
  495.                 status = EDITOR_ERROR_LINE_TOO_LONG;
  496.                 break;
  497.  
  498.             default:
  499.                 status = EDITOR_ERROR_READ_FAILED;
  500.                 break;
  501.             }
  502.         }
  503.         while (status == EDITOR_STATUS_NORMAL);
  504.         if (status != EDITOR_STATUS_EOB)
  505.         {
  506.  
  507.             /* Free incomplete block */
  508.             switch (block_type)
  509.             {
  510.             case BLOCK_TYPE_FONT:
  511.                 free_template_font(new_font);
  512.                 break;
  513.  
  514.             case BLOCK_TYPE_TEMPLATE:
  515.                 free_template(tl, new_template);
  516.                 break;
  517.  
  518.             case BLOCK_TYPE_TEXTLIST:
  519.                 free_template_text_list(new_template);
  520.                 break;
  521.             }
  522.         }
  523.         else
  524.         {
  525.             if (block_type == BLOCK_TYPE_FONT)
  526.             {
  527.                 AddTail((struct List *) & tl->tl_Fonts,
  528.                         (struct Node *) & new_font->tf_MinNode);
  529.             }
  530.             else
  531.             {
  532.                 if (block_type == BLOCK_TYPE_TEMPLATE)
  533.                 {
  534.                     struct Template *tp;
  535.                     struct Box *box;
  536.                     struct BorderData *bd;
  537.                     struct TextData *td;
  538.                     struct GadgetData *gd;
  539.  
  540.                     /* Init new template */
  541.                     tp = new_template;
  542.                     box = &tp->tp_Box;
  543.                     tp->tp_Node.ln_Name = &tp->tp_TemplateName[0];
  544.                     switch (TEMPLATE_GROUP(tp))
  545.                     {
  546.                     case TEMPLATE_GROUP_BORDER:
  547.  
  548.                         /* Init border template */
  549.                         bd = &tp->tp_Data.tp_BorderData;
  550.                         bd->bd_LeftEdge = box->bo_X1;
  551.                         bd->bd_TopEdge = box->bo_Y1;
  552.                         bd->bd_Width = box->bo_X2 - box->bo_X1 + 1;
  553.                         bd->bd_Height = box->bo_Y2 - box->bo_Y1 + 1;
  554.                         (bd + 1)->bd_Type = INTUISUP_DATA_END;
  555.                         break;
  556.  
  557.                     case TEMPLATE_GROUP_TEXT:
  558.  
  559.                         /* Init text template */
  560.                         td = &tp->tp_Data.tp_TextData;
  561.                         td->td_LeftEdge = box->bo_X1;
  562.                         td->td_TopEdge = box->bo_Y1;
  563.                         (td + 1)->td_Type = INTUISUP_DATA_END;
  564.                         break;
  565.  
  566.                     case TEMPLATE_GROUP_GADGET:
  567.  
  568.                         /* Init gadget template */
  569.                         gd = &tp->tp_Data.tp_GadgetData;
  570.                         gd->gd_LeftEdge = box->bo_X1;
  571.                         gd->gd_TopEdge = box->bo_Y1;
  572.                         gd->gd_Width = box->bo_X2 - box->bo_X1 + 1;
  573.                         gd->gd_Height = box->bo_Y2 - box->bo_Y1 + 1;
  574.                         (gd + 1)->gd_Type = INTUISUP_DATA_END;
  575.                         break;
  576.                     }
  577.                     add_template_to_list(tl, tp, FALSE);
  578.                 }
  579.             }
  580.             status = EDITOR_STATUS_NORMAL;
  581.         }
  582.     }
  583.     return (status);
  584. }
  585.  
  586.  /* Parse block of load file */
  587.  
  588. STATIC SHORT
  589. parse_item(struct TemplateList * tl, USHORT block_type, BYTE * keyword,
  590.            BYTE * arg, USHORT mode)
  591. {
  592.     struct TextAttr *ta;
  593.     struct Template *tp;
  594.     struct Box *box;
  595.     struct BorderData *bd;
  596.     struct TextData *td;
  597.     struct GadgetData *gd;
  598.     SHORT status = EDITOR_STATUS_NORMAL;
  599.  
  600.     switch (block_type)
  601.     {
  602.     case BLOCK_TYPE_HEADER:
  603.  
  604.         /* Read header data */
  605.         if (mode == LOAD_MODE_NORMAL)
  606.         {
  607.             struct NewWindow *nwin = &project_new_window;
  608.  
  609.             switch (search_keyword(keyword, &header_keywords[0]))
  610.             {
  611.             case HEADER_ITEM_TYPE_LEFTEDGE:
  612.                 nwin->LeftEdge = atol(arg);
  613.                 break;
  614.  
  615.             case HEADER_ITEM_TYPE_TOPEDGE:
  616.                 nwin->TopEdge = atol(arg);
  617.                 break;
  618.  
  619.             case HEADER_ITEM_TYPE_WIDTH:
  620.                 nwin->Width = atol(arg);
  621.                 break;
  622.  
  623.             case HEADER_ITEM_TYPE_HEIGHT:
  624.                 nwin->Height = atol(arg);
  625.                 break;
  626.  
  627.             case HEADER_ITEM_TYPE_MINW:
  628.                 nwin->MinWidth = atol(arg);
  629.                 break;
  630.  
  631.             case HEADER_ITEM_TYPE_MINH:
  632.                 nwin->MinHeight = atol(arg);
  633.                 break;
  634.  
  635.             case HEADER_ITEM_TYPE_MAXW:
  636.                 nwin->MaxWidth = atol(arg);
  637.                 break;
  638.  
  639.             case HEADER_ITEM_TYPE_MAXH:
  640.                 nwin->MaxHeight = atol(arg);
  641.                 break;
  642.  
  643.             case HEADER_ITEM_TYPE_DETAILPEN:
  644.                 nwin->DetailPen = atol(arg);
  645.                 break;
  646.  
  647.             case HEADER_ITEM_TYPE_BLOCKPEN:
  648.                 nwin->BlockPen = atol(arg);
  649.                 break;
  650.  
  651.             case HEADER_ITEM_TYPE_FLAGS:
  652.                 tl->tl_Flags = atol(arg);
  653.                 break;
  654.  
  655.             case HEADER_ITEM_TYPE_WINFLAGS:
  656.                 nwin->Flags = atol(arg);
  657.                 break;
  658.  
  659.             case HEADER_ITEM_TYPE_IDCMPFLAGS:
  660.                 nwin->IDCMPFlags = atol(arg);
  661.                 break;
  662.  
  663.             case HEADER_ITEM_TYPE_ID:
  664.                 strcpy(&tl->tl_ProjectID[0], arg);
  665.                 break;
  666.  
  667.             case HEADER_ITEM_TYPE_NAME:
  668.                 strcpy(tl->tl_ProjectWinName, arg);
  669.                 break;
  670.             }
  671.         }
  672.         break;
  673.  
  674.     case BLOCK_TYPE_FONT:
  675.  
  676.         /* Read template font data */
  677.         ta = &new_font->tf_TextAttr;
  678.         switch (search_keyword(keyword, &font_keywords[0]))
  679.         {
  680.         case FONT_ITEM_TYPE_NAME:
  681.             status = duplicate_string(arg, (BYTE **) & ta->ta_Name);
  682.             break;
  683.  
  684.         case FONT_ITEM_TYPE_YSIZE:
  685.             ta->ta_YSize = atol(arg);
  686.             break;
  687.         }
  688.         break;
  689.  
  690.     case BLOCK_TYPE_TEMPLATE:
  691.  
  692.         /* Read template data */
  693.         tp = new_template;
  694.         switch (search_keyword(keyword, &template_keywords[0]))
  695.         {
  696.         case TEMPLATE_ITEM_TYPE_NAME:
  697.             strcpy(&tp->tp_TemplateName[0], arg);
  698.             break;
  699.  
  700.         case TEMPLATE_ITEM_TYPE_TYPE:
  701.             tp->tp_Type = atol(arg);
  702.             break;
  703.  
  704.         case TEMPLATE_ITEM_TYPE_FLAGS:
  705.             tp->tp_Flags = atol(arg);
  706.             break;
  707.         }
  708.         break;
  709.  
  710.     case BLOCK_TYPE_BOX:
  711.  
  712.         /* Read box data */
  713.         box = &new_template->tp_Box;
  714.         switch (search_keyword(keyword, &box_keywords[0]))
  715.         {
  716.         case BOX_ITEM_TYPE_X1:
  717.             box->bo_X1 = atol(arg);
  718.             break;
  719.  
  720.         case BOX_ITEM_TYPE_Y1:
  721.             box->bo_Y1 = atol(arg);
  722.             break;
  723.  
  724.         case BOX_ITEM_TYPE_X2:
  725.             box->bo_X2 = atol(arg);
  726.             break;
  727.  
  728.         case BOX_ITEM_TYPE_Y2:
  729.             box->bo_Y2 = atol(arg);
  730.             break;
  731.         }
  732.         break;
  733.  
  734.     case BLOCK_TYPE_TEXTLIST:
  735.  
  736.         /* Read text list */
  737.         switch (search_keyword(keyword, &textlist_keywords[0]))
  738.         {
  739.         case TEXTLIST_ITEM_TYPE_TEXT:
  740.             status = add_template_text_list_entry(new_template, arg);
  741.             break;
  742.         }
  743.         break;
  744.  
  745.     case BLOCK_TYPE_BORDERDATA:
  746.  
  747.         /* Read border data */
  748.         bd = &new_template->tp_Data.tp_BorderData;
  749.         switch (search_keyword(keyword, &borderdata_keywords[0]))
  750.         {
  751.         case BORDERDATA_ITEM_TYPE_TYPE:
  752.             bd->bd_Type = atol(arg);
  753.             break;
  754.         }
  755.         break;
  756.  
  757.     case BLOCK_TYPE_TEXTDATA:
  758.  
  759.         /* Read text data */
  760.         td = &new_template->tp_Data.tp_TextData;
  761.         switch (search_keyword(keyword, &textdata_keywords[0]))
  762.         {
  763.         case TEXTDATA_ITEM_TYPE_TYPE:
  764.             td->td_Type = atol(arg);
  765.             break;
  766.  
  767.         case TEXTDATA_ITEM_TYPE_FLAGS:
  768.             td->td_Flags = atol(arg);
  769.             break;
  770.  
  771.         case TEXTDATA_ITEM_TYPE_TEXT:
  772.             if (td->td_Type == TEXT_DATA_TYPE_TEXT)
  773.             {
  774.                 status = duplicate_string(arg, &td->td_Text);
  775.             }
  776.             else
  777.             {
  778.                 td->td_Text = (BYTE *) atol(arg);
  779.             }
  780.             break;
  781.  
  782.         case TEXTDATA_ITEM_TYPE_TEXTATTR:
  783.             if (!(td->td_TextAttr = open_template_font_by_num(tl,
  784.                                                               (USHORT) atol(arg))))
  785.             {
  786.                 status = EDITOR_ERROR_INVALID_FONT;
  787.             }
  788.             break;
  789.         }
  790.         break;
  791.  
  792.     case BLOCK_TYPE_GADGETDATA:
  793.  
  794.         /* Read gadget data */
  795.         tp = new_template;
  796.         gd = &tp->tp_Data.tp_GadgetData;
  797.         switch (search_keyword(keyword, &gadgetdata_keywords[0]))
  798.         {
  799.         case GADGETDATA_ITEM_TYPE_TYPE:
  800.             gd->gd_Type = atol(arg);
  801.             break;
  802.  
  803.         case GADGETDATA_ITEM_TYPE_FLAGS:
  804.             gd->gd_Flags = atol(arg);
  805.             break;
  806.  
  807.         case GADGETDATA_ITEM_TYPE_TEXT:
  808.             if (*arg == '0')
  809.             {
  810.                 gd->gd_Text = NULL;
  811.             }
  812.             else
  813.             {
  814.                 status = duplicate_string(arg, &gd->gd_Text);
  815.             }
  816.             break;
  817.  
  818.         case GADGETDATA_ITEM_TYPE_TEXTATTR:
  819.             if (!(gd->gd_TextAttr = open_template_font_by_num(tl,
  820.                                                               (USHORT) atol(arg))))
  821.             {
  822.                 status = EDITOR_ERROR_INVALID_FONT;
  823.             }
  824.             break;
  825.  
  826.         case GADGETDATA_ITEM_TYPE_SPECIAL1:
  827.             gd->gd_SpecialData.gd_Data.gd_Data1 = atol(arg);
  828.             break;
  829.  
  830.         case GADGETDATA_ITEM_TYPE_SPECIAL2:
  831.             gd->gd_SpecialData.gd_Data.gd_Data2 = atol(arg);
  832.             break;
  833.  
  834.         case GADGETDATA_ITEM_TYPE_SPECIAL3:
  835.             switch (gd->gd_Type)
  836.             {
  837.             case GADGET_DATA_TYPE_BUTTON:
  838.             case GADGET_DATA_TYPE_CHECK:
  839.             case GADGET_DATA_TYPE_INTEGER:
  840.             case GADGET_DATA_TYPE_SLIDER:
  841.             case GADGET_DATA_TYPE_SCROLLER:
  842.             case GADGET_DATA_TYPE_COUNT:
  843.             case GADGET_DATA_TYPE_PALETTE:
  844.                 gd->gd_SpecialData.gd_Data.gd_Data3 = (VOID *) atol(arg);
  845.                 break;
  846.             case GADGET_DATA_TYPE_STRING:
  847.                 status = duplicate_string(arg,
  848.                                           (BYTE **) & gd->gd_SpecialData.gd_Data.gd_Data3);
  849.                 break;
  850.             case GADGET_DATA_TYPE_MX:
  851.             case GADGET_DATA_TYPE_CYCLE:
  852.                 status = build_template_text_array(tp);
  853.                 break;
  854.             case GADGET_DATA_TYPE_LISTVIEW:
  855.                 gd->gd_SpecialData.gd_ListViewData.gd_ListViewList = &tp->tp_TextList;
  856.                 break;
  857.             }
  858.             break;
  859.         }
  860.         break;
  861.     }
  862.     return (status);
  863. }
  864.  
  865.  /* Search keyword in given list */
  866.  
  867. STATIC USHORT
  868. search_keyword(BYTE * keyword, BYTE ** keyword_list)
  869. {
  870.     BYTE *word;
  871.     USHORT count = 0, num = 0;
  872.  
  873.     while (word = *keyword_list++)
  874.     {
  875.         count++;
  876.         if (!strcmp(word, keyword))
  877.         {
  878.             num = count;
  879.             break;
  880.         }
  881.     }
  882.     return (num);
  883. }
  884.